[IA64] Fix virtualized EFI memory mapping creation for dom0.
authorAlex Williamson <alex.williamson@hp.com>
Thu, 24 Apr 2008 20:02:16 +0000 (14:02 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Thu, 24 Apr 2008 20:02:16 +0000 (14:02 -0600)
EFI uses 4k page, while xen uses 16k page.  For dom0, identity mappings
are setup for EFI_ACPI_RECLAIM_MEMORY etc.  It is possible when seting
up dom0 memory ranges to include some EFI_ACPI_RECLAIM_MEMORY ranges
due to 4k/16k alignment difference.

This patch fixes this issue by scaning memory descriptors twice.  In the
first scan, setup dom0 identity mapping.  In the second scan, setup
dom0 memory mapping.

Signed-off-by: Anthony Xu <anthony.xu@intel.com>
xen/arch/ia64/xen/dom_fw_dom0.c

index 68a6bae63065aaedcd84a5c6244d7e93d961b043..d8ecada2523e71d46483cdb1b2e4313a1a5f9438 100644 (file)
@@ -352,6 +352,15 @@ complete_dom0_memmap(struct domain *d, struct fw_tables *tables)
        efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
        efi_desc_size = ia64_boot_param->efi_memdesc_size;
 
+
+       /* EFI memory descriptor is using 4k page, while xen is using 16k page.
+        * To avoid identity mapping for EFI_ACPI_RECLAIM_MEMORY etc. being
+        * blocked by WB mapping, scan memory descriptor twice.
+        * First: setup identity mapping for EFI_ACPI_RECLAIM_MEMORY etc.
+        * Second: setup mapping for EFI_CONVENTIONAL_MEMORY etc.
+        */
+  
+       /* first scan, setup identity mapping for EFI_ACPI_RECLAIM_MEMORY etc. */
        for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
                const efi_memory_desc_t *md = p;
                efi_memory_desc_t *dom_md = &tables->efi_memmap[tables->num_mds];
@@ -411,6 +420,48 @@ complete_dom0_memmap(struct domain *d, struct fw_tables *tables)
                        tables->num_mds++;
                        break;
 
+               case EFI_CONVENTIONAL_MEMORY:
+               case EFI_LOADER_CODE:
+               case EFI_LOADER_DATA:
+               case EFI_BOOT_SERVICES_CODE:
+               case EFI_BOOT_SERVICES_DATA:
+                       break;
+
+               case EFI_UNUSABLE_MEMORY:
+               case EFI_PAL_CODE:
+                       /*
+                        * We don't really need these, but holes in the
+                        * memory map may cause Linux to assume there are
+                        * uncacheable ranges within a granule.
+                        */
+                       dom_md->type = EFI_UNUSABLE_MEMORY;
+                       dom_md->phys_addr = start;
+                       dom_md->virt_addr = 0;
+                       dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
+                       dom_md->attribute = EFI_MEMORY_WB;
+                       tables->num_mds++;
+                       break;
+
+               default:
+                       /* Print a warning but continue.  */
+                       printk("complete_dom0_memmap: warning: "
+                              "unhandled MDT entry type %u\n", md->type);
+               }
+       }
+
+       /* secend scan, setup mapping for EFI_CONVENTIONAL_MEMORY etc. */
+       for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+               const efi_memory_desc_t *md = p;
+               efi_memory_desc_t *dom_md = &tables->efi_memmap[tables->num_mds];
+               u64 start = md->phys_addr;
+               u64 size = md->num_pages << EFI_PAGE_SHIFT;
+               u64 end = start + size;
+               u64 mpaddr;
+               unsigned long flags;
+
+               switch (md->type) {
+
                case EFI_CONVENTIONAL_MEMORY:
                case EFI_LOADER_CODE:
                case EFI_LOADER_DATA:
@@ -458,27 +509,12 @@ complete_dom0_memmap(struct domain *d, struct fw_tables *tables)
                        break;
                }
 
-               case EFI_UNUSABLE_MEMORY:
-               case EFI_PAL_CODE:
-                       /*
-                        * We don't really need these, but holes in the
-                        * memory map may cause Linux to assume there are
-                        * uncacheable ranges within a granule.
-                        */
-                       dom_md->type = EFI_UNUSABLE_MEMORY;
-                       dom_md->phys_addr = start;
-                       dom_md->virt_addr = 0;
-                       dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
-                       dom_md->attribute = EFI_MEMORY_WB;
-                       tables->num_mds++;
-                       break;
 
                default:
-                       /* Print a warning but continue.  */
-                       printk("complete_dom0_memmap: warning: "
-                              "unhandled MDT entry type %u\n", md->type);
+                       break;
                }
        }
+
        BUG_ON(tables->fw_tables_size <
               sizeof(*tables) +
               sizeof(tables->efi_memmap[0]) * tables->num_mds);